home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / programer2 / icon / Source / Icont / C / Util < prev   
Encoding:
Text File  |  1990-07-20  |  8.0 KB  |  467 lines

  1. /*
  2.  *  util.c -- general utility functions.
  3.  */
  4.  
  5. #include <ctype.h>
  6. #include "../h/config.h"
  7. #include "general.h"
  8. #include "tproto.h"
  9. #include "../h/cpuconf.h"
  10. #include "globals.h"
  11. #include "trans.h"
  12. #include "tree.h"
  13.  
  14.  
  15. extern int optind;
  16.  
  17. extern char *ofile;
  18.  
  19. /*
  20.  * The following code is operating-system dependent [@util.01].  Define the
  21.  *  characters that terminate a file name prefix.
  22.  */
  23.  
  24. #if PORT
  25. #define Prefix "/"
  26. Deliberate Syntax Error
  27. #endif                    /* PORT */
  28.  
  29. #if ARM
  30. #define Prefix ".:"
  31. #endif                    /* ARM */
  32.  
  33. #if AMIGA
  34. #define Prefix "/:"
  35. #endif                    /* AMIGA */
  36.  
  37. #if ATARI_ST
  38. #define Prefix "/:\\"
  39. #endif                    /* ATARI_ST */
  40.  
  41. #if HIGHC_386 || MSDOS || OS2
  42. #define Prefix "/:\\"
  43. #endif                    /* HIGHC_386 || MSDOS || OS2 */
  44.  
  45. #if MACINTOSH
  46. #define Prefix ":"
  47. #endif                    /* MACINTOSH */
  48.  
  49. #if MVS || VM
  50. #define Prefix ""
  51. #endif                    /* MVS || VM */
  52.  
  53. #if UNIX
  54. #define Prefix "/"
  55. #endif                    /* UNIX */
  56.  
  57. #if VMS
  58. #define Prefix "]:"
  59. #endif                    /* VMS */
  60.  
  61. /*
  62.  * End of operating-system specific code.
  63.  */
  64.  
  65. /*
  66.  * Information about Icon functions.
  67.  */
  68.  
  69. /*
  70.  * Number of arguments.
  71.  */
  72.  
  73.  
  74. /*
  75.  * Names of Icon functions.
  76.  */
  77. char *ftable[] = {
  78. #define FncDef(p,n) Lit(p),
  79. #define FncDefV(p) Lit(p),
  80. #include "../h/fdefs.h"
  81. #undef FncDef
  82. #undef FncDefV
  83.    };
  84.  
  85. int ftbsize = sizeof(ftable)/sizeof(char *);
  86.  
  87. /*
  88.  * alloc - allocate n bytes
  89.  */
  90.  
  91. pointer alloc(n)
  92. unsigned int n;
  93.    {
  94.    pointer a;
  95.  
  96.    if (!(a = malloc((msize)n)))
  97.       quit("out of memory");
  98.    return a;
  99.    }
  100.  
  101. /*
  102.  * salloc - allocate and initialize string 
  103.  */
  104.  
  105. char *salloc(s)
  106. char *s;
  107.    {
  108.  
  109.    return strcpy((char *)alloc((unsigned int)(strlen(s)+1)),s);
  110.    }
  111.  
  112. /*
  113.  * tcalloc - allocate and zero m*n bytes
  114.  */
  115. pointer tcalloc(m,n)
  116. unsigned int m, n;
  117.    {
  118.    pointer a;
  119.  
  120.    if (!(a = calloc(m,n)))
  121.       quit("out of memory");
  122.    return a;
  123.    }
  124.  
  125. /*
  126.  * fparse - break a file name down into component parts.
  127.  *  Result is a pointer to a struct of static pointers good until the next call.
  128.  */
  129. struct fileparts *fparse(s)
  130. char *s;
  131.    {
  132. #if ARM
  133.     static char buf[MaxFileName+2];
  134.     static struct fileparts fp;
  135.     char *p;
  136.     char *ext = 0;
  137.     char *extend = 0;
  138.     char *dirend = 0;
  139.     char *s1;
  140.     char *bp = buf;
  141.  
  142.     /* First, skip any filing system prefix */
  143.     s1 = index(s,':');
  144.     if (s1 == NULL)
  145.         s1 = s;
  146.     else
  147.         ++s1;
  148.  
  149.     /* Now, scan backwards through the filename, looking for dots.
  150.      * Record the positions of the final two, for later use.
  151.      */
  152.     p = s1 + strlen(s1);
  153.     fp.name = 0;
  154.     
  155.     while (--p > s1)
  156.     {
  157.            if (*p != '.')
  158.                continue;
  159.  
  160.         if (fp.name == NULL)
  161.         {
  162.             fp.name = p + 1;
  163.             extend = p;
  164.         }
  165.         else
  166.         {
  167.             ext = p + 1;
  168.             dirend = p;
  169.             break;
  170.         }
  171.     }
  172.  
  173.     /* This is the simple case. The filename is a simple name, with no
  174.      * directory part. The extension is therefore null, and the directory
  175.      * is just the filing system prefix, if any.
  176.      */
  177.     if (fp.name == NULL)
  178.     {
  179.         fp.name = s1;
  180.  
  181.         if (s1 == s)
  182.         {
  183.             fp.ext = "";
  184.             fp.dir = "";
  185.         }
  186.         else
  187.         {
  188.             fp.ext = "";
  189.             strncpy(buf, s, s1 - s);
  190.             buf[s1-s] = '\0';
  191.             fp.dir = buf;
  192.         }
  193.  
  194.         return &fp;
  195.     }
  196.  
  197.     /* Now worry about the more complicated cases. First, check the
  198.      * supposed extension, to see if it is one of the valid cases,
  199.      * SourceSuffix, U1Suffix, U2Suffix, or USuffix. For this code
  200.      * to work, these four defined values must start with a dot, and
  201.      * be all in lower case.
  202.      */
  203.     *buf = '.';
  204.     bp = buf + 1;
  205.  
  206.     for (p = ext ? ext : s1; p < extend; ++p)
  207.     {
  208.         *bp++ = tolower(*p);
  209.     }
  210.  
  211.     *bp++ = '\0';
  212.  
  213.     if (strcmp(buf,SourceSuffix) == 0 || strcmp(buf,U1Suffix) == 0
  214.      || strcmp(buf,U2Suffix) == 0 || strcmp(buf,USuffix) == 0)
  215.     {
  216.         fp.ext = buf;
  217.     }
  218.     else
  219.     {
  220.         fp.ext = "";
  221.         bp = buf;
  222.         dirend = extend;
  223.     }
  224.  
  225.     /* We now have the name and extension sorted out. So we just need
  226.      * to copy the directory part into buf (at bp), and set fp.dir.
  227.      */
  228.     if (dirend == NULL)
  229.     {
  230.         if (s1 == s)
  231.             fp.dir = "";
  232.         else
  233.         {
  234.             fp.dir = bp;
  235.  
  236.             while (s < s1)
  237.                 *bp++ = *s++;
  238.  
  239.             *bp = '\0';
  240.         }
  241.     }
  242.     else
  243.     {
  244.         fp.dir = bp;
  245.  
  246.         while (s <= dirend)
  247.             *bp++ = *s++;
  248.  
  249.         *bp = '\0';
  250.     }
  251.  
  252.     return &fp;
  253.  
  254. #else                    /* ARM */
  255.  
  256.    static char buf[MaxFileName+2];
  257.    static struct fileparts fp;
  258.    int n;
  259.    char *p, *q;
  260.    char *index();
  261.  
  262. #if MVS         /* for any compiler which takes member names */
  263.    static char extbuf [MaxFileName+2] ;
  264.  
  265.    p = index(s, '(');
  266.    if (p) {
  267.       fp.member = p+1;
  268.       memcpy(extbuf, s, p-s);
  269.       extbuf [p-s]  = '\0';
  270.       s = extbuf;
  271.    }
  272.    else fp.member = s + strlen(s);
  273. #endif                    /* MVS */
  274.  
  275.    q = s;
  276.    fp.ext = p = s + strlen(s);
  277.    while (--p >= s) {
  278.       if (*p == '.' && *fp.ext == '\0')
  279.          fp.ext = p;
  280.       else if (index(Prefix,*p)) {
  281.          q = p+1;
  282.          break;
  283.          }
  284.       }
  285.    fp.dir = buf;
  286.    n = q - s;
  287.    strncpy(fp.dir,s,n);
  288.    fp.dir[n] = '\0';
  289.    fp.name = buf + n + 1;
  290.    n = fp.ext - q;
  291.    strncpy(fp.name,q,n);
  292.    fp.name[n] = '\0';
  293.    return &fp;
  294.  
  295. #endif                    /* not ARM */
  296.    }
  297.  
  298. /*
  299.  * makename - make a file name, optionally substituting a new dir and/or ext
  300.  */
  301. char *makename(dest,d,name,e)
  302. char *dest, *d, *name, *e;
  303.    {
  304.    struct fileparts fp;
  305.    fp = *fparse(name);
  306.    if (d != NULL)
  307.       fp.dir = d;
  308.    if (e != NULL)
  309.       fp.ext = e;
  310.  
  311. #if ARM
  312.  
  313.    {
  314.       char *p = (*fp.ext ? fp.ext + 1 : "");
  315.       sprintf(dest, "%s%s%s%s", fp.dir, p, (*p ? "." : ""), fp.name);
  316.    }
  317.  
  318. #else                    /* ARM */
  319.  
  320. #if MVS
  321.    if (*fp.member)
  322.       sprintf(dest,"%s%s%s(%s", fp.dir, fp.name, fp.ext, fp.member);
  323.    else
  324. #endif                    /* MVS */
  325.  
  326.    sprintf(dest,"%s%s%s",fp.dir,fp.name,fp.ext);
  327.  
  328. #endif                    /* ARM */
  329.  
  330.    return dest;
  331.    }
  332.  
  333. /*
  334.  * quit - immediate exit with error message
  335.  */
  336.  
  337. novalue quit(msg)
  338. char *msg;
  339.    {
  340.    quitf(msg,"");
  341.    }
  342.  
  343. /*
  344.  * quitf - immediate exit with message format and argument
  345.  */
  346. novalue quitf(msg,arg)
  347. char *msg, *arg;
  348.    {
  349.  
  350.  
  351.    extern char *progname;
  352.    fprintf(stderr,"%s: ",progname);
  353.    fprintf(stderr,msg,arg);
  354.    fprintf(stderr,"\n");
  355.  
  356. #ifndef VarTran
  357.    if (ofile)
  358.       unlink(ofile);            /* remove bad icode file */
  359. #endif                    /* VarTran */
  360.  
  361.    exit(ErrorExit);
  362.    }
  363.  
  364. /*
  365.  * tsyserr is called for fatal errors.  The message s is produced and the
  366.  *  translator exits.
  367.  */
  368. novalue tsyserr(s)
  369. char *s;
  370.    {
  371.  
  372.  
  373.    if (tok_loc.n_file)
  374.       fprintf(stderr, "File %s; ", tok_loc.n_file);
  375.    fprintf(stderr, "Line %d # %s\n", in_line, s);
  376.  
  377.    exit(ErrorExit);
  378.    }
  379.  
  380.  
  381. /*
  382.  * round2 - round an integer up to the next power of 2.
  383.  */
  384. unsigned int round2(n)
  385. unsigned int n;
  386.    {
  387.    unsigned int b = 1;
  388.    while (b < n)
  389.       b <<= 1;
  390.    return b;
  391.    }
  392.  
  393.  
  394. /*
  395.  * sizearg - process -S command option.
  396.  */
  397.  
  398. struct keyptr {            /* structure for listing option chars */
  399.    char *cmd;                /* option character(s) */
  400.    unsigned int *valp;            /* pointer to value word */
  401.    };
  402.  
  403. static struct keyptr keytable[] = {    /* maps keys to store addresses */
  404.  
  405. #define Size(cmd,vname,defalt) cmd, &vname,
  406. #define MinSize(x,y,z)
  407. #include "sizes.h"            /* initialize from "sizes.h" data */
  408. #undef Size
  409. #undef MinSize
  410.    0, 0,                /* terminate with null entry */
  411.    };
  412.  
  413. novalue sizearg(arg,argv)
  414. char *arg;
  415. char **argv;
  416.    {
  417.    struct keyptr *k;            /* key table pointer */
  418.    char *s;                /* value string pointer */
  419.    int v;                /* option value */
  420.  
  421.    for (k = keytable; k->cmd; k++)    /* search for key match */
  422.       if (arg[0] == k->cmd[0] && (arg[0] != 'h' || arg[1] == k->cmd[1]))
  423.          break;
  424.  
  425.    if (k->cmd == NULL)            /* abort if not found */
  426.       quitf("unrecognized -S option: -S%s",arg);
  427.  
  428.    if (arg[0] == 'h')
  429.       s = &arg[2];            /* find value */
  430.    else
  431.       s = &arg[1];
  432.       
  433.    if (*s == '\0') {            /* if value is in next arg */
  434.       s = argv[optind++];
  435.       if (s == NULL)
  436.          quitf("missing value: -S%s", arg);
  437.       }
  438.  
  439.    v = (int)atol(s);                /* convert integer -- check */
  440.    if (v <= 0)
  441.       quitf("illegal value: -S%s", arg);
  442.    *k->valp = v;            /* store result */
  443.    }
  444.  
  445.  
  446. /*
  447.  * smatch - case-insensitive string match - returns nonzero if they match
  448.  */
  449. int smatch(s,t)
  450. char *s, *t;
  451.    {
  452.    char a, b;
  453.    for (;;) {
  454.       while (*s == *t)
  455.          if (*s++ == '\0')
  456.             return 1;
  457.          else
  458.             t++;
  459.       a = *s++;
  460.       b = *t++;
  461.       if (isupper(a))  a = tolower(a);
  462.       if (isupper(b))  b = tolower(b);
  463.       if (a != b)
  464.          return 0;
  465.       }
  466.    }
  467.